package com.example.simulate;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 多线程进程调度模拟程序
 * 1. 使用随机调度算法模拟进程并发执行
 * 2. 可视化三个进程的状态（小球运动）
 * 3. 支持单个进程的暂停/恢复控制
 */
public class ProcessScheduler {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            // 初始化GUI框架
            MainFrame mainFrame = new MainFrame();
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            // 创建并启动调度器
            new ProcessScheduler().startScheduling(mainFrame);
        });
    }

    /**
     * 进程调度器核心逻辑
     */
    private void startScheduling(MainFrame frame) {
        // 创建三个进程线程
        ProcessThread[] processes = {
                new ProcessThread("进程1", frame.panel1, Color.ORANGE),
                new ProcessThread("进程2", frame.panel2, Color.GREEN),
                new ProcessThread("进程3", frame.panel3, Color.BLUE)
        };

        // 启动调度线程
        new Thread(() -> {
            Random random = new Random();
            while (true) {
                int processId = random.nextInt(3); // 随机选择进程
                if (processes[processId].isRunnable()) {
                    processes[processId].executeTimeSlice();
                }
                try {
                    Thread.sleep(10); // 模拟时间片切换间隔
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }).start();
    }
}

/**
 * 主界面框架
 */
class MainFrame extends JFrame {
    final ProcessPanel panel1 = new ProcessPanel("进程1", Color.ORANGE);
    final ProcessPanel panel2 = new ProcessPanel("进程2", Color.GREEN);
    final ProcessPanel panel3 = new ProcessPanel("进程3", Color.BLUE);
    final StatusPanel statusPanel = new StatusPanel();

    public MainFrame() {
        super("多进程并发执行模拟");
        initializeUI();
    }

    private void initializeUI() {
        setSize(850, 500);
        setLocationRelativeTo(null);

        Container contentPane = getContentPane();
        contentPane.setLayout(new GridLayout(4, 1));

        contentPane.add(statusPanel);
        contentPane.add(panel1);
        contentPane.add(panel2);
        contentPane.add(panel3);

        setVisible(true);
    }
}

/**
 * 进程控制面板（抽象公共逻辑）
 */
class ProcessPanel extends JPanel {
    private static final int BALL_SIZE = 60;
    private final JButton toggleButton = new JButton("暂停");
    private final Ball ball = new Ball(50, 35);
    private final AtomicBoolean isRunning = new AtomicBoolean(true);
    private final String processName;
    private final Color ballColor;

    public ProcessPanel(String name, Color color) {
        this.processName = name;
        this.ballColor = color;
        initializePanel();
    }

    private void initializePanel() {
        setLayout(null);
        setBackground(new Color(230, 230, 250));  // Light lavender background
        setBorder(BorderFactory.createTitledBorder(processName));

        toggleButton.setBounds(730, 50, 70, 35);
        toggleButton.setFont(new Font("微软雅黑", Font.BOLD, 12));  // 设置支持中文的字体
        toggleButton.setBackground(new Color(70, 130, 180));
        toggleButton.setForeground(Color.WHITE);
        toggleButton.setFocusPainted(false);
        toggleButton.addActionListener(this::handleToggle);
        add(toggleButton);
    }

    /**
     * 按钮点击事件处理
     */
    private void handleToggle(ActionEvent e) {
        isRunning.set(!isRunning.get());
        toggleButton.setText(isRunning.get() ? "暂停" : "继续");
        StatusPanel.updateStatus(processName, isRunning.get());
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(ballColor);
        g.fillOval(ball.getX(), ball.getY(), BALL_SIZE, BALL_SIZE);
    }

    // 线程安全的位置更新方法
    synchronized void updateBallPosition() {
        if (ball.getX() < 650) {
            ball.move(10);
        } else {
            ball.reset();
        }
        repaint();
    }

    boolean isRunning() {
        return isRunning.get();
    }
}

/**
 * 状态信息面板
 */
class StatusPanel extends JPanel {
    private static final JLabel[] statusLabels = new JLabel[3];

    public StatusPanel() {
        initializePanel();
    }

    private void initializePanel() {
        setLayout(null);
        setBackground(new Color(240, 248, 255));  // Light blue background
        JLabel title = new JLabel("进程并发执行状态监控");
        title.setFont(new Font("微软雅黑", Font.BOLD, 30));  // 设置支持中文的字体
        title.setBounds(250, 10, 500, 50);
        title.setForeground(new Color(70, 130, 180));  // Deep Sky Blue color

        for (int i = 0; i < 3; i++) {
            statusLabels[i] = createStatusLabel(i);
        }

        add(title);
        for (JLabel label : statusLabels) {
            add(label);
        }
    }

    private JLabel createStatusLabel(int index) {
        JLabel label = new JLabel("进程" + (index+1) + "正在运行");
        label.setBounds(250 + 200 * index, 60, 150, 25);
        label.setFont(new Font("微软雅黑", Font.PLAIN, 14));  // 设置支持中文的字体
        label.setForeground(new Color(70, 130, 180));
        label.setBorder(BorderFactory.createRaisedBevelBorder());
        return label;
    }

    static void updateStatus(String processName, boolean isRunning) {
        int index = Integer.parseInt(processName.substring(2)) - 1;
        statusLabels[index].setText(processName + (isRunning ? "正在运行" : "已暂停"));
    }
}

/**
 * 进程执行线程（封装运动逻辑）
 */
class ProcessThread {
    private static final int MOVE_DELAY = 30;
    private final ProcessPanel panel;
    private final String name;

    public ProcessThread(String name, ProcessPanel panel, Color color) {
        this.name = name;
        this.panel = panel;
    }

    void executeTimeSlice() {
        if (panel.isRunning()) {
            panel.updateBallPosition();
            simulateProcessing();
        }
    }

    private void simulateProcessing() {
        try {
            Thread.sleep(MOVE_DELAY);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    boolean isRunnable() {
        return panel.isRunning();
    }
}

/**
 * 小球数据模型
 */
class Ball {
    private int x;
    private final int initialX;
    private final int initialY;

    public Ball(int x, int y) {
        this.initialX = x;
        this.initialY = y;
        reset();
    }

    void move(int xDelta) {
        x += xDelta;
    }

    void reset() {
        x = initialX;
    }

    int getX() {
        return x;
    }

    int getY() {
        return initialY;
    }
}
